#![allow(non_snake_case)]
use leptos::prelude::*;
use shq_common::prelude::{WhereCause, WhereCauses};

use crate::components::{
    client_data_table::ClientDataTable, get_page_config, loading::Loading, server_error::ServerError, ButtonList
};

#[component]
pub fn TableEdit(
    menu_id: u32,
    #[prop(into)] conf_name: Oco<'static, str>,
    #[prop(optional, into)] init_filters: Signal<Vec<WhereCause>>,
    #[prop(optional, into)] custom_buttons: StoredValue<ButtonList>,
    can_update: bool,
) -> impl IntoView {
    let conf_name = StoredValue::new(conf_name.to_string());
    let conf = Resource::new(
        move || conf_name.get_value(),
        move |conf_name| async move {
            let jval_res = get_page_config(menu_id, conf_name).await;
            jval_res
        },
    );
    let list_data_res = Resource::new(
        move || (conf_name.get_value(), init_filters.get()),
        move |(conf_name, init_filters)| async move {
            let filters: WhereCauses = WhereCauses::from(init_filters);
            let fstr = serde_json::to_string(&filters).unwrap();
            let jval_res = get_list_data(menu_id, conf_name, fstr).await;
            jval_res
        },
    );
    view! {
        <Suspense fallback=|| view! { <Loading/> }>
            <Show
                when=move || conf.get().is_some()
                fallback=|| view! { <Loading/> }
            >
                {move || Suspend::new(async move {
                    let conf_res = conf.await;
                    if let Err(err) = conf_res {
                        return view! { <ServerError err_msg=err.to_string().into()/> }.into_any();
                    }
                    let list_data_res = list_data_res.await;
                    if let Err(err) = list_data_res {
                        return view! { <ServerError err_msg=err.to_string().into()/> }.into_any();
                    }
                    let conf= conf_res.unwrap();
                    let list_data=list_data_res.unwrap();
                    let title=conf.title.clone();
                    let list_props=StoredValue::new(conf.list_props.expect("没有配置list_props"));
                    let field_props=StoredValue::new(conf.field_props);
                    view!{
                        <ClientDataTable
                            menu_id=menu_id
                            conf_name
                            title
                            list_props
                            field_props
                            list_data
                            custom_buttons
                            can_update
                        />
                    }.into_any()
                })}
            </Show>
        </Suspense>
    }
}

#[server(GetListDataForClient, "/api/protect")]
async fn get_list_data(
    menu_id: u32,
    conf_name: String,
    filters: String,
) -> Result<Vec<serde_json::Value>, ServerFnError> {
    use crate::auth::get_user_context_with_auth;
    let user = get_user_context_with_auth(menu_id, shq_common::prelude::AuthType::Select).await?;
    let ps = shq_pas_backend::PageService::new(&conf_name, user.user_id, menu_id);
    let filters: WhereCauses = serde_json::from_str(&filters).unwrap();
    let res = ps
        .get_list_data(
            Some(filters),
            None,
            shq_common::prelude::report::DisplayCols::Default,
            1,
            10000,
            None,
        )
        .await;
    match res {
        Ok(data) => {
            if data.1 > 10000 {
                let mess = format!(
                    "实体类{}的记录数有{}条，超过10000条，请使用server_data_table",
                    &conf_name, data.1
                );
                log::error!("{}", &mess);
                return Err(ServerFnError::ServerError(mess));
            }
            Ok(data.0)
        }
        Err(e) => Err(ServerFnError::ServerError(e.to_string())),
    }
}
